package com.homelock.common.util;

import java.text.SimpleDateFormat;
import java.util.*;

import com.alibaba.fastjson.JSONArray;
import com.aliyuncs.dysmsapi.model.v20170525.*;
import com.aliyuncs.exceptions.ClientException;
import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pi.base.util.time.DateTools;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType;
import com.homelock.constants.ErrorSms;
import com.homelock.domain.sms.ActiveSms;
import com.homelock.domain.sms.AliyunProfile;
import com.pi.base.dto.result.ServiceResult;

public class AliYunComSms {
	private static final Logger logger = LoggerFactory.getLogger(AliYunComSms.class);
	private static final String REQUEST_PRODUCT = "Dysmsapi";//短信API产品名称（短信产品名固定，无需修改）
	private static final String REQUEST_DOMAIN = "dysmsapi.aliyuncs.com";//短信API产品域名（接口地址固定，无需修改）
	private static final String ACCESS_KEY_ID = "LTAILG8utH76nQvM";
	private static final String ACCESS_KEY_SECRET = "kZf1ZV6W96nQjdF11rAKnBOZv4m4Kd";
	private static final String SMS_PREFIX = "00";
	private static final Long MAX_PAGE_SIZE = 50L;
	private static final int DEFAULT_PAGE = 1;
	public static ServiceResult<String> sendSms(ActiveSms sms){
		logger.info("[{}]传入参数：{}", (null != sms? sms.getMsgTag():""), sms);
		ServiceResult result = AliyunProfileManager.checkActiveSms(sms);
		if(null != result){
		  return result;
		}
		try {
      AliyunProfile profile = new AliyunProfile(
          REQUEST_PRODUCT, REQUEST_DOMAIN, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
			IAcsClient acsClient = AliyunProfileManager.initializeProfile(profile);
			
			//组装请求对象
			SendSmsRequest request = new SendSmsRequest();
			//使用post提交
			request.setMethod(MethodType.POST);
			//必填:待发送手机号。支持以逗号分隔的形式进行批量调用，批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,
			//验证码类型的短信推荐使用单条调用的方式；发送国际/港澳台消息时，接收号码格式为00+国际区号+号码，如“0085200000000”
			//request.setPhoneNumbers("0084904572090");//越南
			//request.setPhoneNumbers("00917798969911");
			request.setPhoneNumbers( SMS_PREFIX + sms.getRegion() + sms.getPhoneNumber());
			//必填:短信签名-可在短信控制台中找到
			String sign = StringUtils.isBlank(sms.getSign())?StringUtils.EMPTY:sms.getSign();
			request.setSignName(sign);
			//必填:短信模板-可在短信控制台中找到
			request.setTemplateCode(sms.getSmsTemplateCode());
			//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
			//友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
			JSONObject notification = new JSONObject();
	    if(null != sms.getSmsVarMap()){
	      Set<String> keySet = sms.getSmsVarMap().keySet();
	      if(null !=keySet){
	        Iterator<String> it = keySet.iterator();
	        while(it.hasNext()){
	          String key = it.next();
	          notification.put(key, sms.getSmsVarMap().get(key));
	        }
	      }
	    }
			request.setTemplateParam(notification.toString());
			//可选-上行短信扩展码(扩展码字段控制在7位或以下，无特殊需求用户请忽略此字段)
			//request.setSmsUpExtendCode("90997");
			//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
			request.setOutId("33262419890717");
			//请求失败这里会抛ClientException异常
			logger.debug("[{}]使用账号:{}, 密钥：{} 发送短信, 签名为：{}, 用户手机号：{}", 
					sms.getMsgTag(), ACCESS_KEY_ID, ACCESS_KEY_SECRET,
					sign, SMS_PREFIX + sms.getRegion() + sms.getPhoneNumber());
			SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
			if(sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
				logger.info("[{}] 短信发送成功, 请求编号:{}, 业务编号：{}, 返回码：{}, 返回消息:{}", sms.getMsgTag(), 
				    sendSmsResponse.getRequestId(), sendSmsResponse.getBizId(),
				    sendSmsResponse.getCode(), sendSmsResponse.getMessage());
				return ServiceResult.newSuccessResult(null);
			}else{
				logger.info("{}发送短信失败，错误码： {},  返回消息：{}, 请求id: {}", sms.getMsgTag(),
						sendSmsResponse.getCode(), sendSmsResponse.getMessage(), sendSmsResponse.getRequestId());
			}
		} catch (Exception e) {
			logger.error(sms.getMsgTag() + "发送短信出错",e);
		}
		return ServiceResult.newFailResult(ErrorSms.ERR_SMS_SEND_FAIL.getDesc(), ErrorSms.ERR_SMS_SEND_FAIL.getErrorCode());
	}


	/**
	 * 批量发送短信
	 * @param sms
	 * @return
	 */
	public static ServiceResult<SendBatchSmsResponse> sendBatchSms(ActiveSms sms, List<String> phoneList,List<Map> params){
		logger.info("[{}]传入参数：{}", (null != sms? sms.getMsgTag():""), sms);
		ServiceResult result = AliyunProfileManager.checkActiveSms(sms);
		if(null != result){
			return result;
		}
		try {
			AliyunProfile profile = new AliyunProfile(REQUEST_PRODUCT, REQUEST_DOMAIN, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
			IAcsClient acsClient = AliyunProfileManager.initializeProfile(profile);
			SendBatchSmsRequest request = new SendBatchSmsRequest();
			request.setMethod(MethodType.POST);
			request.setPhoneNumberJson(getListJson(phoneList));
			String sign = StringUtils.isBlank(sms.getSign())?StringUtils.EMPTY:sms.getSign();
			String signJson =  getSignJson(sign,phoneList.size());
			request.setSignNameJson(signJson);
			request.setTemplateCode(sms.getSmsTemplateCode());
			request.setTemplateParamJson(getParamsListJson(params));
			logger.info("请求手机号："+request.getPhoneNumberJson());
			logger.debug("[{}]使用账号:{}, 密钥：{} 发送短信, 签名为：{}, 用户手机号数：{}",
					sms.getMsgTag(), ACCESS_KEY_ID, ACCESS_KEY_SECRET,
					sign, phoneList.size() );
			SendBatchSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
			if(sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
				logger.info("[{}] 短信发送成功, 请求编号:{}, 业务编号：{}, 返回码：{}, 返回消息:{}", sms.getMsgTag(),
						sendSmsResponse.getRequestId(), sendSmsResponse.getBizId(),
						sendSmsResponse.getCode(), sendSmsResponse.getMessage());
				return ServiceResult.newSuccessResult(sendSmsResponse);
			}else{
				logger.info("{}发送短信失败，错误码： {},  返回消息：{}, 请求id: {}", sms.getMsgTag(),
						sendSmsResponse.getCode(), sendSmsResponse.getMessage(), sendSmsResponse.getRequestId());
			}
		} catch (Exception e) {
			logger.error(sms.getMsgTag() + "发送短信出错",e);
		}
		return ServiceResult.newFailResult(ErrorSms.ERR_SMS_SEND_FAIL.getDesc(), ErrorSms.ERR_SMS_SEND_FAIL.getErrorCode());
	}


	/**
	 * 查询批量结果
	 * @param bizId
	 * @return
	 * @throws ClientException
	 */
	public static QuerySendDetailsResponse querySendDetails(String phone,String bizId)  {
		try {
			//初始化acsClient,暂不支持region化
			AliyunProfile profile = new AliyunProfile(REQUEST_PRODUCT, REQUEST_DOMAIN, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
			IAcsClient acsClient = AliyunProfileManager.initializeProfile(profile);
			//组装请求对象
			QuerySendDetailsRequest request = new QuerySendDetailsRequest();
			//必填-号码
			request.setPhoneNumber("11111111111");
			//可选-流水号
			request.setBizId(bizId);
			//必填-发送日期 支持30天内记录查询，格式yyyyMMdd
			request.setSendDate(DateTools.getCurDate(DateTools.FORMAT_SIMPLEDATE));
			//必填-页大小
			request.setPageSize(10L);
			//必填-当前页码从1开始计数
			request.setCurrentPage(1L);
			//hint 此处可能会抛出异常，注意catch
			QuerySendDetailsResponse querySendDetailsResponse = acsClient.getAcsResponse(request);
			System.out.println(querySendDetailsResponse.getMessage());
			logger.info(querySendDetailsResponse.getCode());
			logger.info(new ObjectMapper().writeValueAsString(querySendDetailsResponse));
			return querySendDetailsResponse;
		}catch (Exception e) {
			logger.error("查询短信出错",e);
		}
		return null;
	}


	/**
	 * 封装 listToJsonstring
	 * @param phoneList
	 * @return
	 */
	private static String getListJson(List phoneList){
		JSONArray jsonArray=new JSONArray(phoneList);
		return jsonArray.toJSONString();
	}

	/**
	 * 单个sign 封装成相应手机号数的sign string
	 * @param sign
	 * @return
	 */
	private static String getSignJson(String sign,int size){
		String[] array = new String[size];
		Arrays.fill(array,sign);
		return getListJson(Arrays.asList(array));
	}


	public static String getParamsListJson(List<Map> params){
		JSONArray jsonArray = new JSONArray();
		for(Map map:params){
			JSONObject jsonObject = new JSONObject(map);
			jsonArray.add(jsonObject);
		}
		return jsonArray.toJSONString();
	}
	
	public static void main(String[] args) {
	    ActiveSms sms = new ActiveSms();
	    sms.setMsgTag("短信");
	    sms.setPhoneNumber("13757150532");
	    sms.setRegion("86");
	    sms.setSign("科银管家");
	    sms.setSmsSubType("");
	    sms.setSmsTemplateCode("SMS_174811813");
	    Map<String,String> map = new HashMap<String, String>();
	    map.put("username", "xiaomiao");
	    sms.setSmsVarMap(map);
	    sms.setSourceId(57115206555271168L);
	    ServiceResult<String> sendSms = AliYunComSms.sendSms(sms);
	    System.out.println(sendSms);
    }
}
